package com.raymond.cmpp.common.codec;

import cn.hutool.core.util.ClassUtil;
import com.raymond.cmpp.common.codec.annotation.MsgCodec;
import com.raymond.cmpp.common.codec.decoding.BaseDecoder;
import com.raymond.cmpp.common.codec.encodeing.BaseEncoder;

import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 编解码策略
 *
 * @author :  raymond
 * @version :  V1.0
 * @date :  2021-08-05 09:11
 */
public class BaseCodecStrategy {
    private static final Map<Integer, BaseDecoder> DECODER_MAP = new ConcurrentHashMap<>();

    public static void putBaseDecoder(Integer commandId, BaseDecoder baseDecoder) {
        DECODER_MAP.put(commandId, baseDecoder);
    }

    public static BaseDecoder getBaseDecoder(int commandId) {
        return DECODER_MAP.get(commandId);
    }

    private static final Map<Integer, BaseEncoder> ENCODER_MAP = new ConcurrentHashMap<>();

    public static void putBaseEncoder(Integer commandId, BaseEncoder baseEncoder) {
        ENCODER_MAP.put(commandId, baseEncoder);
    }
    public static BaseEncoder getBaseEncoder(int commandId) {
        return ENCODER_MAP.get(commandId);
    }

    /**
     * 初始化编解码类
     * @param packageName 包路径
     * @throws IllegalAccessException 异常
     * @throws InstantiationException 异常
     */
    public static void init(String packageName) throws IllegalAccessException, InstantiationException {
        Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation(packageName, MsgCodec.class);
        for (Class<?> aClass : classes) {
            if (BaseDecoder.class.isAssignableFrom(aClass)) {
                BaseCodecStrategy.putBaseDecoder(aClass.getAnnotation(MsgCodec.class).commandId().getCommandId()
                        , (BaseDecoder) aClass.newInstance());
            }
            if (BaseEncoder.class.isAssignableFrom(aClass)) {
                BaseCodecStrategy.putBaseEncoder(aClass.getAnnotation(MsgCodec.class).commandId().getCommandId()
                        , (BaseEncoder) aClass.newInstance());
            }
        }
    }
}
